<template>
  <div class="main-content" ref="mainContentRef">
    <div class="content-wrapper" :class="{ 'chat-active': isChatActive }">
      <!-- 欢迎语 -->
      <transition name="fade-greeting">
        <div class="greeting-section" v-if="!isChatActive">
          <h1 class="greeting-title">你好 Fanxt_Ja！想聊些什么？</h1>
        </div>
      </transition>

      <!-- 聊天历史记录展示区 -->
      <div class="chat-history-section" v-if="isChatActive">
        <div v-if="isLoadingHistory" class="loading-history">正在加载历史消息...</div>
        <div v-else-if="historyError" class="history-error">{{ historyError }}</div>
        
        <!-- 历史消息列表 -->
        <div
          v-for="message in chatHistory"
          :key="message.id"
          class="message-wrapper"
          :class="{
            'user-message': message.messageType === 'user',
            'assistant-message': message.messageType === 'assistant'
          }"
        >
          <div class="message-bubble">
            <!-- 使用 <pre> 或 white-space: pre-wrap 来保留格式 -->
            <p class="message-content">{{ message.content }}</p>
          </div>
        </div>
      </div>

      <!-- 聊天输入区 -->
      <div class="chat-input-section" ref="chatInputSectionRef">
        <!-- **核心改动：监听新的流式事件** -->
        <ChatInput
          :is-chat-active="isChatActive"
          :current-chat-id="currentChatId"
          :selected-session-character-name="props.selectedSessionCharacterName"
          @add-message="handleAddMessage"
          @update-ai-message="handleUpdateAiMessage"
          @new-chat-created="handleNewChatCreated"
          @new-chat-clicked="handleNewChatButtonClicked"
        />
      </div>
    </div>
  </div>
</template>

<style scoped>
/* 添加样式以支持换行和代码块 */
.message-content {
  white-space: pre-wrap; /* 关键样式 */
  word-wrap: break-word;
}
</style>

<script setup lang="ts" name="MainContent">
import { ref, watch, nextTick, onUnmounted  } from 'vue'
import axios from 'axios'
import ChatInput from './ChatInput.vue'
import { syncService } from '../services/syncService';
import { AppConfig } from '../services/config';

// 1. Props 和 Emits 定义
const props = defineProps<{
  isChatActive: boolean;
  currentChatId: string | null;
  selectedSessionCharacterName: string | null;
}>()

// **Emits 保持不变**，因为与 App.vue 的通信逻辑（创建新会话）没有改变
const emit = defineEmits<{
  (e: 'message-sent', payload: { newChatId: string; characterName: string }): void
  (e: 'new-chat-clicked'): void
}>()

// 2. 聊天历史相关状态
// **修改接口，id可以是数字（来自后端）或字符串（来自前端实时生成）**
interface ChatMessage {
  id: number | string;
  chatId: string;
  messageType: 'user' | 'assistant' | 'system';
  content: string;
}

const chatHistory = ref<ChatMessage[]>([])
const isLoadingHistory = ref(false)
const historyError = ref<string | null>(null)
const mainContentRef = ref<HTMLElement | null>(null)

// --- 2. 新增用于同步的状态 ---
const isWaitingForAudio = ref(false);
const textBuffer = ref('');
const currentAiMessageId = ref<string | null>(null);
let syncTimeout: number | null = null; // 用于超时处理

// 3. 滚动和布局 (保持不变)
const scrollToBottom = async () => {
  await nextTick();
  const container = mainContentRef.value;
  if (container) {
    container.scrollTop = container.scrollHeight;
  }
}

// 4. 获取历史记录 (保持不变)
const fetchChatHistory = async (chatId: string) => {
  isLoadingHistory.value = true;
  historyError.value = null;
  chatHistory.value = [];

  try {
    const response = await axios.get(AppConfig.ai.chatUrl + '/ai/getChatHistory', { params: { chatId } });
    if (response.data?.code === 200 && response.data.data) {
      chatHistory.value = response.data.data.filter((msg: ChatMessage) => msg.messageType !== 'system');
      scrollToBottom();
    } else {
      throw new Error(response.data?.message || '无法解析响应数据');
    }
  } catch (error) {
    console.error('获取聊天历史失败:', error);
    historyError.value = '获取聊天历史失败，请检查网络或稍后再试。';
  } finally {
    isLoadingHistory.value = false;
  }
}

// 监听会话ID变化，加载历史记录 (保持不变)
// 监听 currentChatId 的变化
watch(() => props.currentChatId, (newId, oldId) => {
  // 如果 newId 有值（意味着我们进入或切换到一个会话）
  if (newId) {
    // **核心逻辑**
    // 仅当 oldId 不是 null 时才去获取历史记录。
    // 这意味着我们是从一个已存在的会话切换到另一个，或者从URL首次加载一个会话。
    // 这可以完美避开“从 null 创建新会话”的场景，因为那种情况下 oldId 就是 null。
    if (oldId !== null) {
      fetchChatHistory(newId);
    }
  } else {
    // 如果 newId 为 null（例如：点击了“新建会话”按钮），则清空历史记录
    chatHistory.value = [];
  }
}, { immediate: true }); // immediate: true 保持不变，以处理页面初始加载时就有会话ID的情况

watch(() => syncService.state.isAudioReady, (isReady) => {
  // 确保信号是针对当前正在等待的消息，并且我们确实在等待
  if (isReady && isWaitingForAudio.value && syncService.state.currentSyncId === currentAiMessageId.value) {
    console.log('[MainContent] Audio ready signal received! Releasing text buffer.');
    // if (syncTimeout) clearTimeout(syncTimeout); // 清除超时计时器
    isWaitingForAudio.value = false;
    playBufferedText(); // 播放缓冲的文本
  }
});


// =================================================================
// **5. 核心改动：实现新的事件处理器**
// =================================================================

/**
 * 处理来自 ChatInput 的新消息（用户发送的和AI的占位消息）
 */
const handleAddMessage = (message: any) => {
  // 适配 ChatInput 发出的消息结构到本组件的 ChatMessage 接口
  const formattedMessage: ChatMessage = {
    id: message.id, // 临时客户端ID
    chatId: props.currentChatId || '', // 应该是当前会话ID
    messageType: message.role, // 'user' or 'assistant'
    content: message.content
  };

  // --- 4. 如果是AI的占位消息，开始同步流程 ---
  if (formattedMessage.messageType === 'assistant') {
    isWaitingForAudio.value = true;
    textBuffer.value = ''; // 清空上一轮的缓冲
    currentAiMessageId.value = formattedMessage.id as string;
    syncService.startSession(currentAiMessageId.value);
    
    // 设置超时，5秒后如果还没收到音频信号，则直接显示文本
    // syncTimeout = window.setTimeout(() => {
    //   if (isWaitingForAudio.value) {
    //     console.warn('[MainContent] Waited 5s for audio signal, timeout! Displaying text now.');
    //     isWaitingForAudio.value = false;
    //     playBufferedText();
    //   }
    // }, 5000);
  }

  chatHistory.value.push(formattedMessage);
  scrollToBottom();
}

/**
 * 处理来自 ChatInput 的AI流式消息更新
 */
const handleUpdateAiMessage = (update: { id: string; content: string }) => {
  // --- 5. 核心：缓冲或直接渲染 ---
  if (isWaitingForAudio.value && update.id === currentAiMessageId.value) {
    // 如果在等待音频，则只更新缓冲区
    textBuffer.value = update.content;
  } else {
    // 否则，正常更新聊天记录
    const messageToUpdate = chatHistory.value.find(msg => msg.id === update.id);
    if (messageToUpdate) {
      // 合并缓冲内容和新的流式内容
      const newContent = textBuffer.value + (update.content.startsWith(textBuffer.value) ? update.content.substring(textBuffer.value.length) : update.content);
      messageToUpdate.content = newContent;
      
      if (textBuffer.value) {
        textBuffer.value = ''; // 清空缓冲区
      }
      
      scrollToBottom();
    }
  }
}

/**
 * 当 ChatInput 中发送第一条消息，创建了新会话时触发
 * 这个函数负责通知 App.vue 更新全局状态
 */
const handleNewChatCreated = (payload: { newChatId: string; characterName: string }) => {
  // 这个事件与旧的 message-sent 用途完全一样，所以直接 emit
  emit('message-sent', payload);
}

/**
 * 当用户点击 "新建会话" 按钮时触发
 */
const handleNewChatButtonClicked = () => {
  emit('new-chat-clicked');
}

/**
 * "快进播放" 缓冲区的文本
 */
const playBufferedText = () => {
  const messageToUpdate = chatHistory.value.find(msg => msg.id === currentAiMessageId.value);
  if (!messageToUpdate || !textBuffer.value) {
    // 如果没有找到消息或缓冲区为空，则结束会话
    syncService.endSession();
    return;
  }

  const fullText = textBuffer.value;
  let currentIndex = 0;
  const interval = setInterval(() => {
    // 每次渲染多个字符，实现快进效果
    const chunkSize = Math.max(1, Math.floor(fullText.length / 20)); // 大约20帧播完
    const nextIndex = Math.min(currentIndex + chunkSize, fullText.length);
    messageToUpdate.content = fullText.substring(0, nextIndex);
    currentIndex = nextIndex;
    
    scrollToBottom();

    if (currentIndex >= fullText.length) {
      clearInterval(interval);
      // 快进结束后，清空缓冲区，并结束同步会話
      textBuffer.value = '';
      syncService.endSession();
    }
  }, 20); // 每20毫秒更新一次
}

// 组件卸载时清理计时器
onUnmounted(() => {
  // if (syncTimeout) {
  //   clearTimeout(syncTimeout);
  // }
  syncService.endSession();
});

</script>

<style scoped>
/* --- 滚动容器样式保持不变 --- */
.main-content {
  flex: 1;
  position: relative;
  background-color: #f5f5f5;
  overflow-y: auto; /* 滚动功能由该容器负责 */
  /* 移除 padding，移到 content-wrapper 中 */
  scrollbar-width: thin;
  scrollbar-color: #d1d1d1 #f5f5f5;
}

.main-content::-webkit-scrollbar {
  width: 8px;
}

.main-content::-webkit-scrollbar-track {
  background: #f5f5f5;
}

.main-content::-webkit-scrollbar-thumb {
  background-color: #d1d1d1;
  border-radius: 10px;
  border: 2px solid #f5f5f5;
}

/* --- Wrapper 基础样式保持不变 --- */
.content-wrapper {
  width: 100%;
  max-width: 800px;
  margin: 0 auto;
  position: relative;
  /* 添加 padding，将内容与页面边缘隔开 */
  padding: 40px; 
  /* 确保 wrapper 至少和滚动容器一样高 */
  min-height: 100%; 
  
  /* Flexbox 布局 */
  display: flex;
  flex-direction: column;
  
  /* 初始状态：垂直居中欢迎语 */
  /* justify-content: center; 
  
  /* 这条 transition 是动画效果的关键 */
  /* transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1); */
}
/* --- 修改点 1: 移除 justify-content --- */
.content-wrapper.chat-active {
  /* 
   * 将内容推向两端：
   * 聊天历史在顶部，输入框在底部。
   * 这解决了历史消息不在顶部渲染的问题。
   * 同时，从 `center` 到 `space-between` 的转变会产生平滑的动画效果。
   */
  justify-content: space-between; 
}

.greeting-section {
  text-align: center;
  /* 使用flex布局让标题在剩余空间中垂直居中 */
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 150px; /* 预留输入框的大致高度 */
}

.greeting-title {
  font-size: 32px;
  font-weight: 450;
  color: #333;
  /* margin-bottom: 20px; */
}

/* --- 修改点 2: 让历史记录区域“成长”以填充空间 --- */
.chat-history-section {
   /* 
   * 无需设置 flex: 1, overflow 或 max-height。
   * 它会自然地从顶部开始渲染，并根据内容增加高度。
   * 父容器 .main-content 会处理滚动。
   */
  width: 100%;
  padding: 0 10px;
  padding-bottom: var(--input-section-height, 100px); /* 100px 是备用值 */
  transform: translateX(30px);
}


.loading-history, .history-error {
  text-align: center;
  color: #888;
  padding: 20px;
}

/* --- 聊天气泡样式保持不变 --- */
.message-wrapper {
  display: flex;
  margin-bottom: 24px;
  max-width: 100%;
}

.assistant-message {
  justify-content: flex-start;
}

.user-message {
  justify-content: flex-end;
}

.message-bubble {
  padding: 14px 20px;
  border-radius: 20px;
  max-width: 80%;
  box-shadow: none;
  border: none;
}

.assistant-message .message-bubble {
  background-color: #f0f0f1;
  color: #333;
  border-top-left-radius: 6px;
}

.user-message .message-bubble {
  background-color: #e7f1ff;
  color: #333;
  border-bottom-right-radius: 6px;
}

.message-content {
  margin: 0;
  white-space: pre-wrap;
  word-wrap: break-word;
  font-size: 16px;
  line-height: 1.7;
  color: #1a1a1a;
}

/* --- 输入区域样式保持不变 --- */
.chat-input-section {
  position: absolute; /* 使用绝对定位来实现动画 */
  left: 40px;
  right: 40px;
  width: calc(100% - 80px); /* 宽度减去两边的 padding */
  max-width: 800px; /* 与 .content-wrapper 保持一致 */
  margin: 0 auto;
  z-index: 10;
  
  /* [关键] 定义动画过渡效果 */
  transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1), 
              bottom 0.6s cubic-bezier(0.4, 0, 0.2, 1);
  
  /* 
   * [动画初始状态]
   * 默认情况下（非聊天状态），输入框在 wrapper 的 50% 位置，
   * 并通过 transform 向上偏移自身高度的一半，实现完美垂直居中。
   */
  bottom: 50%;
  transform: translateY(100%);
}

/* 
 * [动画最终状态]
 * 当 .chat-active 类被添加时，输入框移动到底部。
 */
.content-wrapper.chat-active .chat-input-section {
  bottom: 0; /* 贴紧父容器底部 */
  transform: translateY(0);
  
  /* [优化] 激活后改为 sticky 定位，这样它会随着页面滚动停留在底部 */
  position: sticky;
  padding-top: 20px;
  /* 需要背景色以遮盖下方滚动的内容 */
  background-color: #f5f5f5;
}

/* --- 欢迎语动画保持不变 --- */
.fade-greeting-leave-active {
  transition: all 0.4s ease-out;
}

.fade-greeting-leave-to {
  opacity: 0;
  transform: translate(-25px, -20px);
}
</style>